using System;
using System.Net;
using System.Threading;
using System.Linq;
using Xunit;
using Xunit.Abstractions;
using FrameIdentityReq.Network;
using FrameIdentityReq.Frames;

namespace xUnitTest
{
    public class TestSocket
    {
        private readonly ITestOutputHelper Output;

        public TestSocket(ITestOutputHelper output)
        {
            Output = output;
        }

        [Theory]
        [InlineData("127.0.0.1", 2204)]
        // [InlineData("59.110.4.93", 2013)]
        public void TestSendRecevieFrame(string ipaddress, int port)
        {
            //Given
            using (AsyncSocket socket = new AsyncSocket(port, 1024))
            {
                socket.StartReceiving();

                IdentityReqFrame frame = new IdentityReqFrame();
                frame.FactoryCode.Value = 4;
                frame.HardwareSerialNum.Value = "0000000000000241";
                frame.UserName.Value = "ljt";
                frame.PWD.Value = "asdfg";
                frame.CRC.Value = frame.CalculationCRC();

                //When

                //Then
                Assert.RaisedEvent<SocketState> evt = Assert.Raises<SocketState>(
                    (h) => socket.OnReceived += h,
                    (h) => socket.OnReceived -= h,
                    () =>
                    {
                        socket.SendTo(IPAddress.Parse(ipaddress), frame.Buffer.ToArray());
                        Thread.Sleep(1000);
                    });
                Assert.NotNull(evt);
                Assert.Equal(socket, evt.Sender);
                Assert.Equal(frame.Buffer.Count, (int)evt.Arguments.Buffer.Length);
                for (int i = 0; i < frame.Buffer.Count; i++)
                {
                    Assert.Equal($"{i}: {frame.Buffer[i]:X2}", $"{i}: {evt.Arguments.Buffer[i]:X2}");
                }
            }
        }
    }
}